// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include "QvisPersistentParticlesWindow.h"

#include <PersistentParticlesAttributes.h>

#include <QCheckBox>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QButtonGroup>
#include <QRadioButton>
#include <QvisVariableButton.h>


// ****************************************************************************
// Method: QvisPersistentParticlesWindow::QvisPersistentParticlesWindow
//
// Purpose: 
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisPersistentParticlesWindow::QvisPersistentParticlesWindow(const int type,
                         PersistentParticlesAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad)
{
    atts = subj;
}


// ****************************************************************************
// Method: QvisPersistentParticlesWindow::~QvisPersistentParticlesWindow
//
// Purpose: 
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisPersistentParticlesWindow::~QvisPersistentParticlesWindow()
{
}


// ****************************************************************************
// Method: QvisPersistentParticlesWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   Kathleen Biagas, Tue Apr 18 16:34:41 PDT 2023
//   Support Qt6: buttonClicked -> idClicked.
//
// ****************************************************************************

void
QvisPersistentParticlesWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(0);
    topLayout->addLayout(mainLayout);

    QGroupBox * timeGroup = new QGroupBox(central);
    timeGroup->setTitle(tr("Time Slices"));
    topLayout->addWidget(timeGroup);

    QGridLayout *timeLayout = new QGridLayout(timeGroup);
    timeLayout->setContentsMargins(5,5,5,5);
    timeLayout->setSpacing(10);

    // Start
    startPathTypeLabel = new QLabel(tr("Type of path"), central);
    timeLayout->addWidget(startPathTypeLabel,0,0);
    startPathType = new QWidget(central);
    startPathTypeButtonGroup= new QButtonGroup(startPathType);
    QHBoxLayout *startPathTypeLayout = new QHBoxLayout(startPathType);
    startPathTypeLayout->setContentsMargins(0,0,0,0);
    startPathTypeLayout->setSpacing(10);

    QRadioButton *startPathTypePathTypeEnumAbsolute = new QRadioButton(tr("Absolute"), startPathType);
    startPathTypeButtonGroup->addButton(startPathTypePathTypeEnumAbsolute, 0);
    startPathTypeLayout->addWidget(startPathTypePathTypeEnumAbsolute);
    QRadioButton *startPathTypePathTypeEnumRelative = new QRadioButton(tr("Relative"), startPathType);
    startPathTypeButtonGroup->addButton(startPathTypePathTypeEnumRelative, 1);
    startPathTypeLayout->addWidget(startPathTypePathTypeEnumRelative);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(startPathTypeButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(startPathTypeChanged(int)));
#else
    connect(startPathTypeButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(startPathTypeChanged(int)));
#endif
    timeLayout->addWidget(startPathType, 0,1);

    startIndexLabel = new QLabel(tr("Index of first time slice"), central);
    timeLayout->addWidget(startIndexLabel,1,0);
    startIndex = new QLineEdit(central);
    connect(startIndex, SIGNAL(returnPressed()),
            this, SLOT(startIndexProcessText()));
    timeLayout->addWidget(startIndex, 1,1);

    // Stop
    stopPathTypeLabel = new QLabel(tr("Type of path"), central);
    timeLayout->addWidget(stopPathTypeLabel,2,0);
    stopPathType = new QWidget(central);
    stopPathTypeButtonGroup= new QButtonGroup(stopPathType);
    QHBoxLayout *stopPathTypeLayout = new QHBoxLayout(stopPathType);
    stopPathTypeLayout->setContentsMargins(0,0,0,0);
    stopPathTypeLayout->setSpacing(10);
    QRadioButton *stopPathTypePathTypeEnumAbsolute = new QRadioButton(tr("Absolute"), stopPathType);
    stopPathTypeButtonGroup->addButton(stopPathTypePathTypeEnumAbsolute, 0);
    stopPathTypeLayout->addWidget(stopPathTypePathTypeEnumAbsolute);
    QRadioButton *stopPathTypePathTypeEnumRelative = new QRadioButton(tr("Relative"), stopPathType);
    stopPathTypeButtonGroup->addButton(stopPathTypePathTypeEnumRelative, 1);
    stopPathTypeLayout->addWidget(stopPathTypePathTypeEnumRelative);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(stopPathTypeButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(stopPathTypeChanged(int)));
#else
    connect(stopPathTypeButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(stopPathTypeChanged(int)));
#endif
    timeLayout->addWidget(stopPathType, 2,1);

    stopIndexLabel = new QLabel(tr("Index of last time slice"), central);
    timeLayout->addWidget(stopIndexLabel,3,0);
    stopIndex = new QLineEdit(central);
    connect(stopIndex, SIGNAL(returnPressed()),
            this, SLOT(stopIndexProcessText()));
    timeLayout->addWidget(stopIndex, 3,1);

    // Stride
    strideLabel = new QLabel(tr("Skip rate between time slices"), central);
    timeLayout->addWidget(strideLabel,4,0);
    stride = new QLineEdit(central);
    connect(stride, SIGNAL(returnPressed()),
            this, SLOT(strideProcessText()));
    timeLayout->addWidget(stride, 4,1);


    // Coordinate replacement
    QGroupBox * coordinateGroup = new QGroupBox(central);
    coordinateGroup->setTitle(tr("Coordinate replacement"));
    topLayout->addWidget(coordinateGroup);

    QGridLayout *coordinateLayout = new QGridLayout(coordinateGroup);
    coordinateLayout->setContentsMargins(5,5,5,5);
    coordinateLayout->setSpacing(10);


    traceVariableXLabel = new QLabel(tr("X-Coordinate"), central);
    coordinateLayout->addWidget(traceVariableXLabel,1,0);
    int traceVariableXMask = QvisVariableButton::Scalars;
    traceVariableX = new QvisVariableButton(true, true, true, traceVariableXMask, central);
    connect(traceVariableX, SIGNAL(activated(const QString&)),
            this, SLOT(traceVariableXChanged(const QString&)));
    coordinateLayout->addWidget(traceVariableX, 1,1);

    traceVariableYLabel = new QLabel(tr("Y-Coordinate"), central);
    coordinateLayout->addWidget(traceVariableYLabel,2,0);
    int traceVariableYMask = QvisVariableButton::Scalars;
    traceVariableY = new QvisVariableButton(true, true, true, traceVariableYMask, central);
    connect(traceVariableY, SIGNAL(activated(const QString&)),
            this, SLOT(traceVariableYChanged(const QString&)));
    coordinateLayout->addWidget(traceVariableY, 2,1);

    traceVariableZLabel = new QLabel(tr("Z-Coordinate"), central);
    coordinateLayout->addWidget(traceVariableZLabel,3,0);
    int traceVariableZMask = QvisVariableButton::Scalars;
    traceVariableZ = new QvisVariableButton(true, true, true, traceVariableZMask, central);
    connect(traceVariableZ, SIGNAL(activated(const QString&)),
            this, SLOT(traceVariableZChanged(const QString&)));
    coordinateLayout->addWidget(traceVariableZ, 3,1);


    QGroupBox * connectionsGroup = new QGroupBox(central);
    connectionsGroup->setTitle(tr("Connect particles"));
    topLayout->addWidget(connectionsGroup);

    QGridLayout *connectionsLayout = new QGridLayout(connectionsGroup);
    connectionsLayout->setContentsMargins(5,5,5,5);
    connectionsLayout->setSpacing(10);


    connectParticles = new QCheckBox(tr("Connect particles"), central);
    connect(connectParticles, SIGNAL(toggled(bool)),
            this, SLOT(connectParticlesChanged(bool)));
    connectionsLayout->addWidget(connectParticles, 0,0);

    showPoints = new QCheckBox(tr("Show points"), central);
    connect(showPoints, SIGNAL(toggled(bool)),
            this, SLOT(showPointsChanged(bool)));
    connectionsLayout->addWidget(showPoints, 0,1);

    indexVariableLabel = new QLabel(tr("Index variable"), central);
    connectionsLayout->addWidget(indexVariableLabel,1,0);
    int indexVariableMask = QvisVariableButton::Scalars;
    indexVariable = new QvisVariableButton(true, true, true, indexVariableMask, central);
    connect(indexVariable, SIGNAL(activated(const QString&)),
            this, SLOT(indexVariableChanged(const QString&)));
    connectionsLayout->addWidget(indexVariable, 1,1);
}


// ****************************************************************************
// Method: QvisPersistentParticlesWindow::UpdateWindow
//
// Purpose: 
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisPersistentParticlesWindow::UpdateWindow(bool doAll)
{
    QString temp;

    for(int i = 0; i < atts->NumAttributes(); ++i)
    {
        if(!doAll)
        {
            if(!atts->IsSelected(i))
            {
                continue;
            }
        }

        switch(i)
        {
          case PersistentParticlesAttributes::ID_startIndex:
            startIndex->blockSignals(true);
            startIndex->setText(IntToQString(atts->GetStartIndex()));
            startIndex->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_startPathType:
            startPathTypeButtonGroup->blockSignals(true);
            if(startPathTypeButtonGroup->button((int)atts->GetStartPathType()) != 0)
                startPathTypeButtonGroup->button((int)atts->GetStartPathType())->setChecked(true);
            updateStartIndexText();
            startPathTypeButtonGroup->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_stopIndex:
            stopIndex->blockSignals(true);
            stopIndex->setText(IntToQString(atts->GetStopIndex()));
            stopIndex->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_stopPathType:
            stopPathType->blockSignals(true);
            if(stopPathTypeButtonGroup->button((int)atts->GetStopPathType()) != 0)
                stopPathTypeButtonGroup->button((int)atts->GetStopPathType())->setChecked(true);
            updateStopIndexText();
            stopPathType->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_stride:
            stride->blockSignals(true);
            stride->setText(IntToQString(atts->GetStride()));
            stride->blockSignals(true);
            break;
          case PersistentParticlesAttributes::ID_traceVariableX:
            traceVariableX->blockSignals(true);
            traceVariableX->setText(QString(atts->GetTraceVariableX().c_str()));
            traceVariableX->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_traceVariableY:
            traceVariableY->blockSignals(true);
            traceVariableY->setText(QString(atts->GetTraceVariableY().c_str()));
            traceVariableY->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_traceVariableZ:
            traceVariableZ->blockSignals(true);
            traceVariableZ->setText(QString(atts->GetTraceVariableZ().c_str()));
            traceVariableZ->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_connectParticles:
            showPoints->setEnabled( atts->GetConnectParticles() );

            indexVariable->setEnabled( atts->GetConnectParticles() );
            if(indexVariableLabel)
                indexVariableLabel->setEnabled( atts->GetConnectParticles() );

            connectParticles->blockSignals(true);
            connectParticles->setChecked(atts->GetConnectParticles());
            connectParticles->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_showPoints:
            showPoints->blockSignals(true);
            showPoints->setChecked(atts->GetShowPoints());
            showPoints->blockSignals(false);
            break;
          case PersistentParticlesAttributes::ID_indexVariable:
            indexVariable->blockSignals(true);
            indexVariable->setText(QString(atts->GetIndexVariable().c_str()));
            indexVariable->blockSignals(false);
            break;
        }
    }
}


// ****************************************************************************
// Method: QvisPersistentParticlesWindow::GetCurrentValues
//
// Purpose: 
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisPersistentParticlesWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);

    // Do startIndex
    if(which_widget == PersistentParticlesAttributes::ID_startIndex || doAll)
    {
        int val;
        if(LineEditGetInt(startIndex, val))
            atts->SetStartIndex(val);
        else
        {
            ResettingError(tr("Index of first time slice"),
                IntToQString(atts->GetStartIndex()));
            atts->SetStartIndex(atts->GetStartIndex());
        }
    }

    // Do stopIndex
    if(which_widget == PersistentParticlesAttributes::ID_stopIndex || doAll)
    {
        int val;
        if(LineEditGetInt(stopIndex, val))
            atts->SetStopIndex(val);
        else
        {
            ResettingError(tr("Index of last time slice"),
                IntToQString(atts->GetStopIndex()));
            atts->SetStopIndex(atts->GetStopIndex());
        }
    }

    // Do stride
    if(which_widget == PersistentParticlesAttributes::ID_stride || doAll)
    {
        int val;
        if(LineEditGetInt(stride, val))
            atts->SetStride(val);
        else
        {
            ResettingError(tr("Skip rate between time slices"),
                IntToQString(atts->GetStride()));
            atts->SetStride(atts->GetStride());
        }
    }

}


//
// Qt Slot functions
//


void
QvisPersistentParticlesWindow::startIndexProcessText()
{
    GetCurrentValues(PersistentParticlesAttributes::ID_startIndex);
    Apply();
}

void
QvisPersistentParticlesWindow::startPathTypeChanged(int val)
{
    if(val != atts->GetStartPathType())
    {
        atts->SetStartPathType(PersistentParticlesAttributes::PathTypeEnum(val));
        SetUpdate(false);
        Apply();
    }
    updateStartIndexText();
}

void
QvisPersistentParticlesWindow::updateStartIndexText()
{
    if( atts->GetStartPathType() == 0 )
    {
        startIndexLabel->setText(tr("Index of the first time slice"));
    }
    else
    {
        startIndexLabel->setText(tr("Number of slices backwards in time"));
    }
}

void
QvisPersistentParticlesWindow::stopIndexProcessText()
{
    GetCurrentValues(PersistentParticlesAttributes::ID_stopIndex);
    Apply();
}


void
QvisPersistentParticlesWindow::stopPathTypeChanged(int val)
{
    if(val != atts->GetStopPathType())
    {
        atts->SetStopPathType(PersistentParticlesAttributes::PathTypeEnum(val));
        SetUpdate(false);
        Apply();
    }
    updateStopIndexText();
}

void
QvisPersistentParticlesWindow::updateStopIndexText()
{
    if( atts->GetStopPathType() == 0 )
    {
        stopIndexLabel->setText(tr("Index of the last time slice"));
    }
    else
    {
        stopIndexLabel->setText(tr("Number of slices forward in time"));
    }
}

void
QvisPersistentParticlesWindow::strideProcessText()
{
    GetCurrentValues(PersistentParticlesAttributes::ID_stride);
    Apply();
}


void
QvisPersistentParticlesWindow::traceVariableXChanged(const QString &varName)
{
    atts->SetTraceVariableX(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisPersistentParticlesWindow::traceVariableYChanged(const QString &varName)
{
    atts->SetTraceVariableY(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisPersistentParticlesWindow::traceVariableZChanged(const QString &varName)
{
    atts->SetTraceVariableZ(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisPersistentParticlesWindow::connectParticlesChanged(bool val)
{
    atts->SetConnectParticles(val);
    Apply();
}


void
QvisPersistentParticlesWindow::showPointsChanged(bool val)
{
    atts->SetShowPoints(val);
    Apply();
}


void
QvisPersistentParticlesWindow::indexVariableChanged(const QString &varName)
{
    atts->SetIndexVariable(varName.toStdString());
    SetUpdate(false);
    Apply();
}
